![[SwiftUI] PhotosPickerのonChangeをiOS17以上とiOS16以下の出しわけをきれいに描きたい](https://images.ctfassets.net/ct0aopd36mqt/wp-thumbnail-291ab56731465588aade0a1c471324b7/8ec78a461f25144ed01585a448b8974b/swift-ui-eyecatch.png)
[SwiftUI] PhotosPickerのonChangeをiOS17以上とiOS16以下の出しわけをきれいに描きたい
こんにちは。きんくまです。
SwiftUI勉強中です。
ViewのonChangeがiOS17から書き方が変わったとのことで、iOS16以下と出しわけが必要になっていました。
それでPhotosPickerのonChangeをうまく書きたいと思っていろいろと調べてようやく書けましたので記録です(メチャクチャはまった)
はまったポイントとしては、ジェネリクスとか、引数にoptionalが入っているときに中でguard文を書こうとしたけどビルドエラーになるところです。
optional対策で@ViewBuilderを使いました。
guard文はやめてif文にしました。
あとViewModifierの方で書こうとしたけど、そっちはうまくいかなかったです
import SwiftUI
import PhotosUI
private extension PhotosPicker {
@ViewBuilder
func onChange_iOS17<T: Equatable>(item: T?, action: @escaping (T) -> Void) -> some View {
if let item {
if #available(iOS 17.0, *) {
onChange(of: item, initial: true) { oldValue, newValue in
action(newValue)
}
} else {
onChange(of: item) { newItem in
action(newItem)
}
}
} else {
self
}
}
}
struct ContentView: View {
@State var photoPickerSelectedImage: PhotosPickerItem?
var body: some View {
PhotosPicker(selection: $photoPickerSelectedImage, matching: .images, preferredItemEncoding: .automatic, photoLibrary: .shared()) {
Text("フォトライブラリーから選択")
}
.onChange_iOS17(item: photoPickerSelectedImage) { item in
// ここに処理を書く
print("選択されたよ!")
}
}
}